home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / lib / python2.6 / dist-packages / Alacarte / MenuEditor.pyc (.txt) < prev    next >
Encoding:
Python Compiled Bytecode  |  2009-04-20  |  28.3 KB  |  928 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyc (Python 2.6)
  3.  
  4. import os
  5. import re
  6. import xml.dom.minidom as xml
  7. import locale
  8. import gmenu
  9. from Alacarte import util
  10.  
  11. class Menu:
  12.     tree = None
  13.     visible_tree = None
  14.     path = None
  15.     dom = None
  16.  
  17.  
  18. class MenuEditor:
  19.     __undo = []
  20.     __redo = []
  21.     
  22.     def __init__(self):
  23.         self.locale = locale.getdefaultlocale()[0]
  24.         self._MenuEditor__loadMenus()
  25.  
  26.     
  27.     def __loadMenus(self):
  28.         self.applications = Menu()
  29.         self.applications.tree = gmenu.lookup_tree('applications.menu', gmenu.FLAGS_SHOW_EMPTY | gmenu.FLAGS_INCLUDE_EXCLUDED | gmenu.FLAGS_INCLUDE_NODISPLAY | gmenu.FLAGS_SHOW_ALL_SEPARATORS)
  30.         self.applications.visible_tree = gmenu.lookup_tree('applications.menu')
  31.         self.applications.path = os.path.join(util.getUserMenuPath(), self.applications.tree.get_menu_file())
  32.         if not os.path.isfile(self.applications.path):
  33.             self.applications.dom = xml.dom.minidom.parseString(util.getUserMenuXml(self.applications.tree))
  34.         else:
  35.             self.applications.dom = xml.dom.minidom.parse(self.applications.path)
  36.         self._MenuEditor__remove_whilespace_nodes(self.applications.dom)
  37.         self.settings = Menu()
  38.         self.settings.tree = gmenu.lookup_tree('settings.menu', gmenu.FLAGS_SHOW_EMPTY | gmenu.FLAGS_INCLUDE_EXCLUDED | gmenu.FLAGS_INCLUDE_NODISPLAY | gmenu.FLAGS_SHOW_ALL_SEPARATORS)
  39.         self.settings.visible_tree = gmenu.lookup_tree('settings.menu')
  40.         self.settings.path = os.path.join(util.getUserMenuPath(), self.settings.tree.get_menu_file())
  41.         if not os.path.isfile(self.settings.path):
  42.             self.settings.dom = xml.dom.minidom.parseString(util.getUserMenuXml(self.settings.tree))
  43.         else:
  44.             self.settings.dom = xml.dom.minidom.parse(self.settings.path)
  45.         self._MenuEditor__remove_whilespace_nodes(self.settings.dom)
  46.         self.save(True)
  47.  
  48.     
  49.     def save(self, from_loading = False):
  50.         for menu in ('applications', 'settings'):
  51.             fd = open(getattr(self, menu).path, 'w')
  52.             fd.write(re.sub('\n[\\s]*([^\n<]*)\n[\\s]*</', '\\1</', getattr(self, menu).dom.toprettyxml().replace('<?xml version="1.0" ?>\n', '')))
  53.             fd.close()
  54.         
  55.         if not from_loading:
  56.             self._MenuEditor__loadMenus()
  57.         
  58.  
  59.     
  60.     def quit(self):
  61.         for file_name in os.listdir(util.getUserItemPath()):
  62.             if file_name[-6:-2] in ('redo', 'undo'):
  63.                 file_path = os.path.join(util.getUserItemPath(), file_name)
  64.                 os.unlink(file_path)
  65.                 continue
  66.         
  67.         for file_name in os.listdir(util.getUserDirectoryPath()):
  68.             if file_name[-6:-2] in ('redo', 'undo'):
  69.                 file_path = os.path.join(util.getUserDirectoryPath(), file_name)
  70.                 os.unlink(file_path)
  71.                 continue
  72.         
  73.         for file_name in os.listdir(util.getUserMenuPath()):
  74.             if file_name[-6:-2] in ('redo', 'undo'):
  75.                 file_path = os.path.join(util.getUserMenuPath(), file_name)
  76.                 os.unlink(file_path)
  77.                 continue
  78.         
  79.  
  80.     
  81.     def revert(self):
  82.         for name in ('applications', 'settings'):
  83.             menu = getattr(self, name)
  84.             self.revertTree(menu.tree.root)
  85.             path = os.path.join(util.getUserMenuPath(), menu.tree.get_menu_file())
  86.             
  87.             try:
  88.                 os.unlink(path)
  89.             except OSError:
  90.                 pass
  91.  
  92.             if not os.path.isfile(menu.path):
  93.                 menu.dom = xml.dom.minidom.parseString(util.getUserMenuXml(menu.tree))
  94.             else:
  95.                 menu.dom = xml.dom.minidom.parse(menu.path)
  96.             self._MenuEditor__remove_whilespace_nodes(menu.dom)
  97.         
  98.         self._MenuEditor__undo = []
  99.         self._MenuEditor__redo = []
  100.         self.save()
  101.  
  102.     
  103.     def revertTree(self, menu):
  104.         for child in menu.get_contents():
  105.             if child.get_type() == gmenu.TYPE_DIRECTORY:
  106.                 self.revertTree(child)
  107.                 continue
  108.             if child.get_type() == gmenu.TYPE_ENTRY:
  109.                 self.revertItem(child)
  110.                 continue
  111.         
  112.         self.revertMenu(menu)
  113.  
  114.     
  115.     def undo(self):
  116.         if len(self._MenuEditor__undo) == 0:
  117.             return None
  118.         files = self._MenuEditor__undo.pop()
  119.         redo = []
  120.         for file_path in files:
  121.             new_path = file_path.rsplit('.', 1)[0]
  122.             redo_path = util.getUniqueRedoFile(new_path)
  123.             data = open(new_path).read()
  124.             open(redo_path, 'w').write(data)
  125.             data = open(file_path).read()
  126.             open(new_path, 'w').write(data)
  127.             os.unlink(file_path)
  128.             redo.append(redo_path)
  129.         
  130.         for name in ('applications', 'settings'):
  131.             menu = getattr(self, name)
  132.             if not os.path.isfile(menu.path):
  133.                 menu.dom = xml.dom.minidom.parseString(util.getUserMenuXml(menu.tree))
  134.             else:
  135.                 menu.dom = xml.dom.minidom.parse(menu.path)
  136.             self._MenuEditor__remove_whilespace_nodes(menu.dom)
  137.         
  138.         self._MenuEditor__redo.append(redo)
  139.  
  140.     
  141.     def redo(self):
  142.         if len(self._MenuEditor__redo) == 0:
  143.             return None
  144.         files = self._MenuEditor__redo.pop()
  145.         undo = []
  146.         for file_path in files:
  147.             new_path = file_path.rsplit('.', 1)[0]
  148.             undo_path = util.getUniqueUndoFile(new_path)
  149.             data = open(new_path).read()
  150.             open(undo_path, 'w').write(data)
  151.             data = open(file_path).read()
  152.             open(new_path, 'w').write(data)
  153.             os.unlink(file_path)
  154.             undo.append(undo_path)
  155.         
  156.         for name in ('applications', 'settings'):
  157.             menu = getattr(self, name)
  158.             if not os.path.isfile(menu.path):
  159.                 menu.dom = xml.dom.minidom.parseString(util.getUserMenuXml(menu.tree))
  160.             else:
  161.                 menu.dom = xml.dom.minidom.parse(menu.path)
  162.             self._MenuEditor__remove_whilespace_nodes(menu.dom)
  163.         
  164.         self._MenuEditor__undo.append(undo)
  165.  
  166.     
  167.     def getMenus(self, parent = None):
  168.         if parent == None:
  169.             yield self.applications.tree.root
  170.             yield self.settings.tree.root
  171.         else:
  172.             for menu in parent.get_contents():
  173.                 if menu.get_type() == gmenu.TYPE_DIRECTORY:
  174.                     yield (menu, self._MenuEditor__isVisible(menu))
  175.                     continue
  176.             
  177.  
  178.     
  179.     def getItems(self, menu):
  180.         for item in menu.get_contents():
  181.             if item.get_type() == gmenu.TYPE_SEPARATOR:
  182.                 yield (item, True)
  183.                 continue
  184.             if item.get_type() == gmenu.TYPE_ENTRY and item.get_desktop_file_id()[-19:] == '-usercustom.desktop':
  185.                 continue
  186.             
  187.             yield (item, self._MenuEditor__isVisible(item))
  188.         
  189.  
  190.     
  191.     def canRevert(self, item):
  192.         if item.get_type() == gmenu.TYPE_ENTRY:
  193.             if util.getItemPath(item.get_desktop_file_id()):
  194.                 path = util.getUserItemPath()
  195.                 if os.path.isfile(os.path.join(path, item.get_desktop_file_id())):
  196.                     return True
  197.             
  198.         elif item.get_type() == gmenu.TYPE_DIRECTORY:
  199.             if item.get_desktop_file_path():
  200.                 file_id = os.path.split(item.get_desktop_file_path())[1]
  201.             else:
  202.                 file_id = item.get_menu_id() + '.directory'
  203.             if util.getDirectoryPath(file_id):
  204.                 path = util.getUserDirectoryPath()
  205.                 if os.path.isfile(os.path.join(path, file_id)):
  206.                     return True
  207.             
  208.         
  209.         return False
  210.  
  211.     
  212.     def setVisible(self, item, visible):
  213.         dom = self._MenuEditor__getMenu(item).dom
  214.         if item.get_type() == gmenu.TYPE_ENTRY:
  215.             self._MenuEditor__addUndo([
  216.                 self._MenuEditor__getMenu(item),
  217.                 item])
  218.             menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(item.get_parent()), dom, dom)
  219.             if visible:
  220.                 self._MenuEditor__addXmlFilename(menu_xml, dom, item.get_desktop_file_id(), 'Include')
  221.                 self._MenuEditor__writeItem(item, no_display = False)
  222.             else:
  223.                 self._MenuEditor__addXmlFilename(menu_xml, dom, item.get_desktop_file_id(), 'Exclude')
  224.             self._MenuEditor__addXmlTextElement(menu_xml, 'AppDir', util.getUserItemPath(), dom)
  225.         elif item.get_type() == gmenu.TYPE_DIRECTORY:
  226.             self._MenuEditor__addUndo([
  227.                 self._MenuEditor__getMenu(item),
  228.                 item])
  229.             if len(item.get_contents()) == 0:
  230.                 return None
  231.             menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(item), dom, dom)
  232.             for node in self._MenuEditor__getXmlNodesByName([
  233.                 'Deleted',
  234.                 'NotDeleted'], menu_xml):
  235.                 node.parentNode.removeChild(node)
  236.             
  237.             if visible:
  238.                 self._MenuEditor__writeMenu(item, no_display = False)
  239.             else:
  240.                 self._MenuEditor__writeMenu(item, no_display = True)
  241.             self._MenuEditor__addXmlTextElement(menu_xml, 'DirectoryDir', util.getUserDirectoryPath(), dom)
  242.         
  243.         self.save()
  244.  
  245.     
  246.     def createItem(self, parent, icon, name, comment, command, use_term, before = None, after = None):
  247.         file_id = self._MenuEditor__writeItem(None, icon, name, comment, command, use_term)
  248.         self.insertExternalItem(file_id, parent.menu_id, before, after)
  249.  
  250.     
  251.     def insertExternalItem(self, file_id, parent_id, before = None, after = None):
  252.         parent = self._MenuEditor__findMenu(parent_id)
  253.         dom = self._MenuEditor__getMenu(parent).dom
  254.         self._MenuEditor__addItem(parent, file_id, dom)
  255.         self._MenuEditor__positionItem(parent, ('Item', file_id), before, after)
  256.         self._MenuEditor__addUndo([
  257.             self._MenuEditor__getMenu(parent),
  258.             ('Item', file_id)])
  259.         self.save()
  260.  
  261.     
  262.     def createMenu(self, parent, icon, name, comment, before = None, after = None):
  263.         file_id = self._MenuEditor__writeMenu(None, icon, name, comment)
  264.         self.insertExternalMenu(file_id, parent.menu_id, before, after)
  265.  
  266.     
  267.     def insertExternalMenu(self, file_id, parent_id, before = None, after = None):
  268.         menu_id = file_id.rsplit('.', 1)[0]
  269.         parent = self._MenuEditor__findMenu(parent_id)
  270.         dom = self._MenuEditor__getMenu(parent).dom
  271.         self._MenuEditor__addXmlDefaultLayout(self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom), dom)
  272.         menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent) + '/' + menu_id, dom, dom)
  273.         self._MenuEditor__addXmlTextElement(menu_xml, 'Directory', file_id, dom)
  274.         self._MenuEditor__positionItem(parent, ('Menu', menu_id), before, after)
  275.         self._MenuEditor__addUndo([
  276.             self._MenuEditor__getMenu(parent),
  277.             ('Menu', file_id)])
  278.         self.save()
  279.  
  280.     
  281.     def createSeparator(self, parent, before = None, after = None):
  282.         self._MenuEditor__positionItem(parent, ('Separator',), before, after)
  283.         self._MenuEditor__addUndo([
  284.             self._MenuEditor__getMenu(parent),
  285.             ('Separator',)])
  286.         self.save()
  287.  
  288.     
  289.     def editItem(self, item, icon, name, comment, command, use_term, parent = None, final = True):
  290.         if icon == item.get_icon() and name == item.get_name() and comment == item.get_comment() and command == item.get_exec() and use_term == item.get_launch_in_terminal():
  291.             return None
  292.         if not parent:
  293.             parent = item.get_parent()
  294.         
  295.         if final:
  296.             self._MenuEditor__addUndo([
  297.                 self._MenuEditor__getMenu(parent),
  298.                 item])
  299.         
  300.         self._MenuEditor__writeItem(item, icon, name, comment, command, use_term)
  301.         if final:
  302.             dom = self._MenuEditor__getMenu(parent).dom
  303.             menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom)
  304.             self._MenuEditor__addXmlTextElement(menu_xml, 'AppDir', util.getUserItemPath(), dom)
  305.         
  306.         self.save()
  307.  
  308.     
  309.     def editMenu(self, menu, icon, name, comment, final = True):
  310.         if icon == menu.get_icon() and name == menu.get_name() and comment == menu.get_comment():
  311.             return None
  312.         dom = self._MenuEditor__getMenu(menu).dom
  313.         menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(menu), dom, dom)
  314.         file_id = self._MenuEditor__writeMenu(menu, icon, name, comment)
  315.         if final:
  316.             self._MenuEditor__addXmlTextElement(menu_xml, 'DirectoryDir', util.getUserDirectoryPath(), dom)
  317.             self._MenuEditor__addUndo([
  318.                 self._MenuEditor__getMenu(menu),
  319.                 menu])
  320.         
  321.         self.save()
  322.  
  323.     
  324.     def copyItem(self, item, new_parent, before = None, after = None):
  325.         dom = self._MenuEditor__getMenu(new_parent).dom
  326.         file_path = item.get_desktop_file_path()
  327.         keyfile = util.DesktopParser(file_path)
  328.         keyfile.set('Categories', ('',))
  329.         keyfile.set('Hidden', False)
  330.         file_id = util.getUniqueFileId(item.get_name(), '.desktop')
  331.         out_path = os.path.join(util.getUserItemPath(), file_id)
  332.         keyfile.write(open(out_path, 'w'))
  333.         self._MenuEditor__addItem(new_parent, file_id, dom)
  334.         self._MenuEditor__positionItem(new_parent, ('Item', file_id), before, after)
  335.         self._MenuEditor__addUndo([
  336.             self._MenuEditor__getMenu(new_parent),
  337.             ('Item', file_id)])
  338.         self.save()
  339.         return file_id
  340.  
  341.     
  342.     def moveItem(self, item, new_parent, before = None, after = None):
  343.         undo = []
  344.         if item.get_parent() != new_parent:
  345.             self.deleteItem(item)
  346.             undo.append(item)
  347.             file_id = self.copyItem(item, new_parent)
  348.             item = ('Item', file_id)
  349.             undo.append(item)
  350.         
  351.         self._MenuEditor__positionItem(new_parent, item, before, after)
  352.         undo.append(self._MenuEditor__getMenu(new_parent))
  353.         self._MenuEditor__addUndo(undo)
  354.         self.save()
  355.  
  356.     
  357.     def moveMenu(self, menu, new_parent, before = None, after = None):
  358.         parent = new_parent
  359.         while parent.get_parent():
  360.             parent = parent.get_parent()
  361.             if parent == menu:
  362.                 return False
  363.             continue
  364.             parent == menu
  365.         if new_parent == menu:
  366.             return False
  367.         if self._MenuEditor__getMenu(menu) != self._MenuEditor__getMenu(new_parent):
  368.             return False
  369.         if menu.get_parent() != new_parent:
  370.             dom = self._MenuEditor__getMenu(menu).dom
  371.             root_path = self._MenuEditor__getPath(menu).split('/', 1)[0]
  372.             xml_root = self._MenuEditor__getXmlMenu(root_path, dom, dom)
  373.             old_path = self._MenuEditor__getPath(menu).split('/', 1)[1]
  374.             self._MenuEditor__addXmlMove(xml_root, old_path, new_path, dom)
  375.         
  376.         self._MenuEditor__positionItem(new_parent, menu, before, after)
  377.         self._MenuEditor__addUndo([
  378.             self._MenuEditor__getMenu(new_parent)])
  379.         self.save()
  380.  
  381.     
  382.     def moveSeparator(self, separator, new_parent, before = None, after = None):
  383.         self._MenuEditor__positionItem(new_parent, separator, before, after)
  384.         self._MenuEditor__addUndo([
  385.             self._MenuEditor__getMenu(new_parent)])
  386.         self.save()
  387.  
  388.     
  389.     def deleteItem(self, item):
  390.         self._MenuEditor__addUndo([
  391.             item])
  392.         self._MenuEditor__writeItem(item, hidden = True)
  393.         self.save()
  394.  
  395.     
  396.     def deleteMenu(self, menu):
  397.         dom = self._MenuEditor__getMenu(menu).dom
  398.         menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(menu), dom, dom)
  399.         self._MenuEditor__addDeleted(menu_xml, dom)
  400.         self._MenuEditor__addUndo([
  401.             self._MenuEditor__getMenu(menu)])
  402.         self.save()
  403.  
  404.     
  405.     def deleteSeparator(self, item):
  406.         parent = item.get_parent()
  407.         contents = parent.get_contents()
  408.         contents.remove(item)
  409.         layout = self._MenuEditor__createLayout(contents)
  410.         dom = self._MenuEditor__getMenu(parent).dom
  411.         menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom)
  412.         self._MenuEditor__addXmlLayout(menu_xml, layout, dom)
  413.         self._MenuEditor__addUndo([
  414.             self._MenuEditor__getMenu(item.get_parent())])
  415.         self.save()
  416.  
  417.     
  418.     def revertItem(self, item):
  419.         if not self.canRevert(item):
  420.             return None
  421.         self._MenuEditor__addUndo([
  422.             item])
  423.         
  424.         try:
  425.             os.remove(item.get_desktop_file_path())
  426.         except OSError:
  427.             self.canRevert(item)
  428.             self.canRevert(item)
  429.         except:
  430.             self.canRevert(item)
  431.  
  432.         self.save()
  433.  
  434.     
  435.     def revertMenu(self, menu):
  436.         if not self.canRevert(menu):
  437.             return None
  438.         if not menu.get_desktop_file_path():
  439.             return None
  440.         self._MenuEditor__addUndo([
  441.             menu])
  442.         file_id = os.path.split(menu.get_desktop_file_path())[1]
  443.         path = os.path.join(util.getUserDirectoryPath(), file_id)
  444.         
  445.         try:
  446.             os.remove(path)
  447.         except OSError:
  448.             menu.get_desktop_file_path()
  449.             menu.get_desktop_file_path()
  450.             self.canRevert(menu)
  451.         except:
  452.             menu.get_desktop_file_path()
  453.  
  454.         self.save()
  455.  
  456.     
  457.     def __addUndo(self, items):
  458.         self._MenuEditor__undo.append([])
  459.         for item in items:
  460.             if isinstance(item, Menu):
  461.                 file_path = item.path
  462.             elif isinstance(item, tuple):
  463.                 if item[0] == 'Item':
  464.                     file_path = os.path.join(util.getUserItemPath(), item[1])
  465.                     if not os.path.isfile(file_path):
  466.                         file_path = util.getItemPath(item[1])
  467.                     
  468.                 elif item[0] == 'Menu':
  469.                     file_path = os.path.join(util.getUserDirectoryPath(), item[1])
  470.                     if not os.path.isfile(file_path):
  471.                         file_path = util.getDirectoryPath(item[1])
  472.                     
  473.                 
  474.             elif item.get_type() == gmenu.TYPE_DIRECTORY:
  475.                 if item.get_desktop_file_path() == None:
  476.                     continue
  477.                 
  478.                 file_path = os.path.join(util.getUserDirectoryPath(), os.path.split(item.get_desktop_file_path())[1])
  479.                 if not os.path.isfile(file_path):
  480.                     file_path = item.get_desktop_file_path()
  481.                 
  482.             elif item.get_type() == gmenu.TYPE_ENTRY:
  483.                 file_path = os.path.join(util.getUserItemPath(), item.get_desktop_file_id())
  484.                 if not os.path.isfile(file_path):
  485.                     file_path = item.get_desktop_file_path()
  486.                 
  487.             
  488.             data = open(file_path).read()
  489.             undo_path = util.getUniqueUndoFile(file_path)
  490.             open(undo_path, 'w').write(data)
  491.             self._MenuEditor__undo[-1].append(undo_path)
  492.         
  493.  
  494.     
  495.     def __getMenu(self, item):
  496.         root = item.get_parent()
  497.         if not root:
  498.             root = item
  499.         else:
  500.             while True:
  501.                 if root.get_parent():
  502.                     root = root.get_parent()
  503.                     continue
  504.                 break
  505.         if root.menu_id == self.applications.tree.root.menu_id:
  506.             return self.applications
  507.         return self.settings
  508.  
  509.     
  510.     def __findMenu(self, menu_id, parent = None):
  511.         if parent == None:
  512.             menu = self._MenuEditor__findMenu(menu_id, self.applications.tree.root)
  513.             if menu != None:
  514.                 return menu
  515.             return self._MenuEditor__findMenu(menu_id, self.settings.tree.root)
  516.         parent == None
  517.         if menu_id == self.applications.tree.root.menu_id:
  518.             return self.applications.tree.root
  519.         if menu_id == self.settings.tree.root.menu_id:
  520.             return self.settings.tree.root
  521.         for item in parent.get_contents():
  522.             if item.get_type() == gmenu.TYPE_DIRECTORY:
  523.                 if item.menu_id == menu_id:
  524.                     return item
  525.                 menu = self._MenuEditor__findMenu(menu_id, item)
  526.                 if menu != None:
  527.                     return menu
  528.                 continue
  529.             menu != None
  530.         
  531.  
  532.     
  533.     def __isVisible(self, item):
  534.         if item.get_type() == gmenu.TYPE_ENTRY:
  535.             if not item.get_is_excluded():
  536.                 pass
  537.             return not item.get_is_nodisplay()
  538.         menu = self._MenuEditor__getMenu(item)
  539.         if menu == self.applications:
  540.             root = self.applications.visible_tree.root
  541.         elif menu == self.settings:
  542.             root = self.settings.visible_tree.root
  543.         
  544.         if item.get_type() == gmenu.TYPE_DIRECTORY:
  545.             if self._MenuEditor__findMenu(item.menu_id, root) == None:
  546.                 return False
  547.         
  548.         return True
  549.  
  550.     
  551.     def __getPath(self, menu, path = None):
  552.         if not path:
  553.             path = menu.tree.root.get_menu_id()
  554.         
  555.         if menu.get_parent():
  556.             path = self._MenuEditor__getPath(menu.get_parent(), path)
  557.             path += '/'
  558.             path += menu.menu_id
  559.         
  560.         return path
  561.  
  562.     
  563.     def __getXmlMenu(self, path, element, dom):
  564.         if '/' in path:
  565.             (name, path) = path.split('/', 1)
  566.         else:
  567.             name = path
  568.             path = ''
  569.         found = None
  570.         for node in self._MenuEditor__getXmlNodesByName('Menu', element):
  571.             for child in self._MenuEditor__getXmlNodesByName('Name', node):
  572.                 if child.childNodes[0].nodeValue == name:
  573.                     if path:
  574.                         found = self._MenuEditor__getXmlMenu(path, node, dom)
  575.                     else:
  576.                         found = node
  577.                     break
  578.                     continue
  579.             
  580.             if found:
  581.                 break
  582.                 continue
  583.         
  584.         if not found:
  585.             node = self._MenuEditor__addXmlMenuElement(element, name, dom)
  586.             if path:
  587.                 found = self._MenuEditor__getXmlMenu(path, node, dom)
  588.             else:
  589.                 found = node
  590.         
  591.         return found
  592.  
  593.     
  594.     def __addXmlMenuElement(self, element, name, dom):
  595.         node = dom.createElement('Menu')
  596.         self._MenuEditor__addXmlTextElement(node, 'Name', name, dom)
  597.         return element.appendChild(node)
  598.  
  599.     
  600.     def __addXmlTextElement(self, element, name, text, dom):
  601.         for temp in element.childNodes:
  602.             if temp.nodeName == name:
  603.                 if temp.childNodes[0].nodeValue == text:
  604.                     return None
  605.                 continue
  606.             temp.childNodes[0].nodeValue == text
  607.         
  608.         node = dom.createElement(name)
  609.         text = dom.createTextNode(text)
  610.         node.appendChild(text)
  611.         return element.appendChild(node)
  612.  
  613.     
  614.     def __addXmlFilename(self, element, dom, filename, type = 'Include'):
  615.         for node in self._MenuEditor__getXmlNodesByName([
  616.             'Include',
  617.             'Exclude'], element):
  618.             if node.childNodes[0].nodeName == 'Filename' and node.childNodes[0].childNodes[0].nodeValue == filename:
  619.                 element.removeChild(node)
  620.                 continue
  621.         
  622.         node = dom.createElement(type)
  623.         node.appendChild(self._MenuEditor__addXmlTextElement(node, 'Filename', filename, dom))
  624.         return element.appendChild(node)
  625.  
  626.     
  627.     def __addDeleted(self, element, dom):
  628.         node = dom.createElement('Deleted')
  629.         return element.appendChild(node)
  630.  
  631.     
  632.     def __writeItem(self, item = None, icon = None, name = None, comment = None, command = None, use_term = None, no_display = None, startup_notify = None, hidden = None):
  633.         if item:
  634.             file_path = item.get_desktop_file_path()
  635.             file_id = item.get_desktop_file_id()
  636.             keyfile = util.DesktopParser(file_path)
  637.         elif item == None and name == None:
  638.             raise Exception('New menu items need a name')
  639.         else:
  640.             file_id = util.getUniqueFileId(name, '.desktop')
  641.             keyfile = util.DesktopParser()
  642.         if icon:
  643.             keyfile.set('Icon', icon)
  644.             keyfile.set('Icon', icon, self.locale)
  645.         
  646.         if name:
  647.             keyfile.set('Name', name)
  648.             keyfile.set('Name', name, self.locale)
  649.         
  650.         if comment:
  651.             keyfile.set('Comment', comment)
  652.             keyfile.set('Comment', comment, self.locale)
  653.         
  654.         if command:
  655.             keyfile.set('Exec', command)
  656.         
  657.         if use_term != None:
  658.             keyfile.set('Terminal', use_term)
  659.         
  660.         if no_display != None:
  661.             keyfile.set('NoDisplay', no_display)
  662.         
  663.         if startup_notify != None:
  664.             keyfile.set('StartupNotify', startup_notify)
  665.         
  666.         if hidden != None:
  667.             keyfile.set('Hidden', hidden)
  668.         
  669.         out_path = os.path.join(util.getUserItemPath(), file_id)
  670.         keyfile.write(open(out_path, 'w'))
  671.         return file_id
  672.  
  673.     
  674.     def __writeMenu(self, menu = None, icon = None, name = None, comment = None, no_display = None):
  675.         if menu:
  676.             file_id = os.path.split(menu.get_desktop_file_path())[1]
  677.             file_path = menu.get_desktop_file_path()
  678.             keyfile = util.DesktopParser(file_path)
  679.         elif menu == None and name == None:
  680.             raise Exception('New menus need a name')
  681.         else:
  682.             file_id = util.getUniqueFileId(name, '.directory')
  683.             keyfile = util.DesktopParser(file_type = 'Directory')
  684.         if icon:
  685.             keyfile.set('Icon', icon)
  686.         
  687.         if name:
  688.             keyfile.set('Name', name)
  689.             keyfile.set('Name', name, self.locale)
  690.         
  691.         if comment:
  692.             keyfile.set('Comment', comment)
  693.             keyfile.set('Comment', comment, self.locale)
  694.         
  695.         if no_display != None:
  696.             keyfile.set('NoDisplay', no_display)
  697.         
  698.         out_path = os.path.join(util.getUserDirectoryPath(), file_id)
  699.         keyfile.write(open(out_path, 'w'))
  700.         return file_id
  701.  
  702.     
  703.     def __getXmlNodesByName(self, name, element):
  704.         for child in element.childNodes:
  705.             if child.nodeType == xml.dom.Node.ELEMENT_NODE:
  706.                 if isinstance(name, str) and child.nodeName == name:
  707.                     yield child
  708.                 elif isinstance(name, list) or isinstance(name, tuple):
  709.                     if child.nodeName in name:
  710.                         yield child
  711.                     
  712.                 
  713.             isinstance(name, tuple)
  714.         
  715.  
  716.     
  717.     def __remove_whilespace_nodes(self, node):
  718.         remove_list = []
  719.         for child in node.childNodes:
  720.             if child.nodeType == xml.dom.minidom.Node.TEXT_NODE:
  721.                 child.data = child.data.strip()
  722.                 if not child.data.strip():
  723.                     remove_list.append(child)
  724.                 
  725.             child.data.strip()
  726.             if child.hasChildNodes():
  727.                 self._MenuEditor__remove_whilespace_nodes(child)
  728.                 continue
  729.         
  730.         for node in remove_list:
  731.             node.parentNode.removeChild(node)
  732.         
  733.  
  734.     
  735.     def __addXmlMove(self, element, old, new, dom):
  736.         if not self._MenuEditor__undoMoves(element, old, new, dom):
  737.             node = dom.createElement('Move')
  738.             node.appendChild(self._MenuEditor__addXmlTextElement(node, 'Old', old, dom))
  739.             node.appendChild(self._MenuEditor__addXmlTextElement(node, 'New', new, dom))
  740.             return element.insertBefore(node, element.firstChild)
  741.  
  742.     
  743.     def __addXmlLayout(self, element, layout, dom):
  744.         for node in self._MenuEditor__getXmlNodesByName('Layout', element):
  745.             element.removeChild(node)
  746.         
  747.         node = dom.createElement('Layout')
  748.         for order in layout.order:
  749.             if order[0] == 'Separator':
  750.                 child = dom.createElement('Separator')
  751.                 node.appendChild(child)
  752.                 continue
  753.             if order[0] == 'Filename':
  754.                 child = self._MenuEditor__addXmlTextElement(node, 'Filename', order[1], dom)
  755.                 continue
  756.             if order[0] == 'Menuname':
  757.                 child = self._MenuEditor__addXmlTextElement(node, 'Menuname', order[1], dom)
  758.                 continue
  759.             if order[0] == 'Merge':
  760.                 child = dom.createElement('Merge')
  761.                 child.setAttribute('type', order[1])
  762.                 node.appendChild(child)
  763.                 continue
  764.         
  765.         return element.appendChild(node)
  766.  
  767.     
  768.     def __addXmlDefaultLayout(self, element, dom):
  769.         for node in self._MenuEditor__getXmlNodesByName('DefaultLayout', element):
  770.             element.removeChild(node)
  771.         
  772.         node = dom.createElement('DefaultLayout')
  773.         node.setAttribute('inline', 'false')
  774.         return element.appendChild(node)
  775.  
  776.     
  777.     def __createLayout(self, items):
  778.         layout = Layout()
  779.         layout.order = []
  780.         layout.order.append([
  781.             'Merge',
  782.             'menus'])
  783.         for item in items:
  784.             if isinstance(item, tuple):
  785.                 if item[0] == 'Separator':
  786.                     layout.parseSeparator()
  787.                 elif item[0] == 'Menu':
  788.                     layout.parseMenuname(item[1])
  789.                 elif item[0] == 'Item':
  790.                     layout.parseFilename(item[1])
  791.                 
  792.             item[0] == 'Separator'
  793.             if item.get_type() == gmenu.TYPE_DIRECTORY:
  794.                 layout.parseMenuname(item.get_menu_id())
  795.                 continue
  796.             if item.get_type() == gmenu.TYPE_ENTRY:
  797.                 layout.parseFilename(item.get_desktop_file_id())
  798.                 continue
  799.             if item.get_type() == gmenu.TYPE_SEPARATOR:
  800.                 layout.parseSeparator()
  801.                 continue
  802.         
  803.         layout.order.append([
  804.             'Merge',
  805.             'files'])
  806.         return layout
  807.  
  808.     
  809.     def __addItem(self, parent, file_id, dom):
  810.         xml_parent = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom)
  811.         self._MenuEditor__addXmlFilename(xml_parent, dom, file_id, 'Include')
  812.  
  813.     
  814.     def __deleteItem(self, parent, file_id, dom, before = None, after = None):
  815.         xml_parent = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom)
  816.         self._MenuEditor__addXmlFilename(xml_parent, dom, file_id, 'Exclude')
  817.  
  818.     
  819.     def __positionItem(self, parent, item, before = None, after = None):
  820.         if not before and not after:
  821.             return None
  822.         if after:
  823.             index = parent.contents.index(after) + 1
  824.         elif before:
  825.             index = parent.contents.index(before)
  826.         
  827.         contents = parent.contents
  828.         
  829.         try:
  830.             contents.remove(item)
  831.         except:
  832.             pass
  833.  
  834.         contents.insert(index, item)
  835.         layout = self._MenuEditor__createLayout(contents)
  836.         dom = self._MenuEditor__getMenu(parent).dom
  837.         menu_xml = self._MenuEditor__getXmlMenu(self._MenuEditor__getPath(parent), dom, dom)
  838.         self._MenuEditor__addXmlLayout(menu_xml, layout, dom)
  839.  
  840.     
  841.     def __undoMoves(self, element, old, new, dom):
  842.         nodes = []
  843.         matches = []
  844.         original_old = old
  845.         final_old = old
  846.         for node in self._MenuEditor__getXmlNodesByName([
  847.             'Move'], element):
  848.             nodes.insert(0, node)
  849.         
  850.         for node in nodes:
  851.             xml_old = node.getElementsByTagName('Old')[0]
  852.             xml_new = node.getElementsByTagName('New')[0]
  853.             if xml_new.childNodes[0].nodeValue == old:
  854.                 matches.append(node)
  855.                 final_old = xml_old.childNodes[0].nodeValue
  856.                 continue
  857.         
  858.         for node in matches:
  859.             element.removeChild(node)
  860.         
  861.         if len(matches) > 0:
  862.             for node in nodes:
  863.                 xml_old = node.getElementsByTagName('Old')[0]
  864.                 xml_new = node.getElementsByTagName('New')[0]
  865.                 path = os.path.split(xml_new.childNodes[0].nodeValue)
  866.                 if path[0] == original_old:
  867.                     element.removeChild(node)
  868.                     for node in dom.getElementsByTagName('Menu'):
  869.                         name_node = node.getElementsByTagName('Name')[0]
  870.                         name = name_node.childNodes[0].nodeValue
  871.                         if name == os.path.split(new)[1]:
  872.                             root_path = dom.getElementsByTagName('Menu')[0].getElementsByTagName('Name')[0].childNodes[0].nodeValue
  873.                             xml_menu = self._MenuEditor__getXmlMenu(root_path + '/' + new, dom, dom)
  874.                             for app_dir in node.getElementsByTagName('AppDir'):
  875.                                 xml_menu.appendChild(app_dir)
  876.                             
  877.                             for dir_dir in node.getElementsByTagName('DirectoryDir'):
  878.                                 xml_menu.appendChild(dir_dir)
  879.                             
  880.                             parent = node.parentNode
  881.                             parent.removeChild(node)
  882.                             continue
  883.                     
  884.                     node = dom.createElement('Move')
  885.                     node.appendChild(self._MenuEditor__addXmlTextElement(node, 'Old', xml_old.childNodes[0].nodeValue, dom))
  886.                     node.appendChild(self._MenuEditor__addXmlTextElement(node, 'New', os.path.join(new, path[1]), dom))
  887.                     element.appendChild(node)
  888.                     continue
  889.             
  890.             if final_old == new:
  891.                 return True
  892.             node = dom.createElement('Move')
  893.             node.appendChild(self._MenuEditor__addXmlTextElement(node, 'Old', final_old, dom))
  894.             node.appendChild(self._MenuEditor__addXmlTextElement(node, 'New', new, dom))
  895.             return element.appendChild(node)
  896.  
  897.  
  898.  
  899. class Layout:
  900.     
  901.     def __init__(self, node = None):
  902.         self.order = []
  903.  
  904.     
  905.     def parseMenuname(self, value):
  906.         self.order.append([
  907.             'Menuname',
  908.             value])
  909.  
  910.     
  911.     def parseSeparator(self):
  912.         self.order.append([
  913.             'Separator'])
  914.  
  915.     
  916.     def parseFilename(self, value):
  917.         self.order.append([
  918.             'Filename',
  919.             value])
  920.  
  921.     
  922.     def parseMerge(self, merge_type = 'all'):
  923.         self.order.append([
  924.             'Merge',
  925.             merge_type])
  926.  
  927.  
  928.